package com.yanqu.road.server.cmd.bag;

import com.yanqu.road.entity.bag.UseGoodsResult;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eGoodsType;
import com.yanqu.road.entity.player.UserBagItem;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.pb.bag.BagProto;
import com.yanqu.road.server.cmd.base.AbstractCommand;
import com.yanqu.road.server.command.Cmd;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.travelbook.TravelBookModule;
import com.yanqu.road.server.gameplayer.module.player.BagModule;
import com.yanqu.road.server.logic.bag.BaseUseGoods;
import com.yanqu.road.server.manger.config.GoodsMgr;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import java.math.BigInteger;
import java.util.Map;

@Cmd(code = Protocol.S_BAG_USE_GOODS, desc = "使用物品")
public class UseGoodsCmd extends AbstractCommand {

    private int goodsId;

    private long count;

    private long param;

    private String param2 = "";

    private UseGoodsResult result = null;

    @Override
    public boolean parseData(YanQuMessage packet) throws Exception {
        BagProto.BagUseGoodsReqMsg reqMsg = BagProto.BagUseGoodsReqMsg.parseFrom(packet.getBytes());
        goodsId = reqMsg.getGoodsId();
        count = reqMsg.getCount();
        param = reqMsg.getParam();
        if (reqMsg.hasParam2()) {
            param2 = reqMsg.getParam2();
        }
        return true;
    }

    @Override
    public void execute(GamePlayer player, YanQuMessage packet) throws Exception {
        BagModule bagModule = player.getModule(BagModule.class);
        UserBagItem bagItem = bagModule.getUserBagItem(goodsId);
        if (bagItem == null || bagItem.getNum() <= 0) {
            //点击任意钱庄外观的解锁/升级按钮，且道具不足(金算盘和摇钱树)
            if(goodsId == GameConfig.HOUSE_BANK_SKIN_ITEM_230000 || goodsId == GameConfig.HOUSE_BANK_SKIN_ITEM_230001){
                player.notifyListener(eGamePlayerEventType.RechargeBankSkin.getValue(), 0);
            }
            ret = GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
            return;
        }
        GoodsInfo goodsInfo = GoodsMgr.getGoodsById(goodsId);
        if(null == goodsInfo){
            ret = GameErrorCode.E_GOODS_NO_EXIST;
            return;
        }

        BaseUseGoods useGoodsEntity = BaseUseGoods.getUseGoodsEntity(player, goodsInfo, param, param2);
        if(null == useGoodsEntity){
            ret = GameErrorCode.E_BAG_ITEM_USE_TYPE_UNKNOWN;
            return;
        }

        if (checkTravelBookPack(player, goodsInfo)) {
            return;
        }

        result = useGoodsEntity.useGoods(count);
    }

    /**
     * 校验旅行册卡包
     *
     * @param player    玩家
     * @param goodsInfo 卡包信息
     * @return boolean
     */
    private boolean checkTravelBookPack(GamePlayer player, GoodsInfo goodsInfo) {
        if (goodsInfo.getType() == eGoodsType.TravelBookRandomPack.getValue()) { // 旅行册随机卡包需要校验还需要多少包能把卡册升满级
            int maxNum = player.getModule(TravelBookModule.class).getAlbumRestNumGetMaxLevel(goodsId);
            if (maxNum == 0) {
                ret = GameErrorCode.E_TRAVEL_BOOK_ALL_CARD_CAN_GET_MAX_LEVEL;
                return true;
            }
            count = Math.min(count, maxNum);
        }

        if (goodsInfo.getType() == eGoodsType.TravelBookOptionalPack.getValue()) { // 旅行册自选卡包需要校验还需要选择的各类卡牌是否超过到达满级的上限
            Property property = PropertyHelper.parseStringToProperty(param2);
            Map<Integer, BigInteger> goods = property.getGoods();
            TravelBookModule module = player.getModule(TravelBookModule.class);
            for (Map.Entry<Integer, BigInteger> kv : goods.entrySet()) {
                int cardId = kv.getKey();
                long cnt = kv.getValue().longValue();
                int rest = module.getCardRestNumGetMaxLevel(cardId, new Property());
                if (rest == -1 || cnt > rest) { // 自选数量大于需要的数量
                    ret = GameErrorCode.E_TRAVEL_BOOK_ALL_CARD_CAN_GET_MAX_LEVEL;
                    return true;
                }
            }
        }

        return false;
    }


    @Override
    public void sendData(GamePlayer player) {
        BagProto.BagUseGoodsRespMsg.Builder respMsg = BagProto.BagUseGoodsRespMsg.newBuilder();
        respMsg.setRet(ret);
        respMsg.setGoodsId(goodsId);
        respMsg.setCount(count);
        if(0 == ret) {
            if(null != result){
                respMsg.setRet(result.getRet());
                respMsg.setReward(result.getReward());
                respMsg.setSpecialReward(result.isSpecialReward());
                respMsg.addAllRewardList(result.getRewardList());
            }else {
                respMsg.setReward("");
            }
        }
        player.sendPacket(Protocol.U_BAG_USE_GOODS, respMsg);
    }

}
